<?php

namespace org\phpstruct\db\PDO;

use org\phpstruct\core;
use org\phpstruct\db;
use org\phpstruct\db\I;

class PDOStatement extends \PDOStatement {

    public $stmt = null;
    private $dbconn = null;
    private $querystring = null;
    public static $typemap = array(
        'resource' => \PDO::PARAM_LOB,
        'integer' => \PDO::PARAM_INT,
        'string' => \PDO::PARAM_STR,
        'NULL' => \PDO::PARAM_NULL,
        'boolean' => \PDO::PARAM_BOOL
    );

    public function __construct($dbconn=null, $stmt=null) {
        new parent();
        $this->dbconn = $dbconn;
        $this->stmt = $stmt;
    }

//

    public function setQueryString($sql) {
        $this->querystring = $sql;
    }

//

    public function getQueryString() {
        return $this->querystring;
    }

//
    //	bool bindParam ( mixed $parameter , mixed &$variable [, int $data_type [, int $length [, mixed $driver_options ]]] )
    public function bindValue($parameter, $value, $data_type = null, $blob="no") {

        if (\is_null($data_type)) {
            $phptype = \gettype($value);
            $data_type = self::$typemap[$phptype];
        }

        return parent::bindValue($parameter, $value, $data_type);
    }

//
    //	bool closeCursor ( void )
    //	int columnCount ( void )
    //	string errorCode ( void )
    //	array errorInfo ( void )

    /**
     * @param $input_parameters array
     */
    public function execute($input_parameters = array()) {

        if (is_resource($this->stmt)) {
            $res = oci_execute($this->stmt, OCI_DEFAULT);
            if ($res) {
                return $res;
            } else {
                $err = oci_error($this->stmt);
                OperationLogger::log("OCI ERROR " . var_export($err, true));
                throw new Exception($err['message'] . $err['sqltext'], $err['code']);
            }
        } else {
            return parent::execute($input_parameters);
        }
    }

//

    public function default_execute($input_parameters = array()) {

        if (is_resource($this->stmt)) {

            $res = oci_execute($this->stmt, OCI_DEFAULT);

            if ($res) {
                return $res;
            } else {
                $err = oci_error($this->stmt);
                OperationLogger::log("OCI ERROR " . var_export($err, true));
                throw new Exception($err['message'] . $err['sqltext'], $err['code']);
            }
        } else {
            return parent::execute($input_parameters);
        }
    }

//
    //	mixed fetch ([ int $fetch_style [, int $cursor_orientation [, int $cursor_offset ]]] )
    public function fetchAll($fetch_style=null, $column_index =null, $ctor_args = null) {

        try {

            if (is_resource($this->stmt)) {

                $rs = array();
                while ($row = oci_fetch_array($this->stmt, OCI_ASSOC)) {
                    array_push($rs, $row);
                }

                oci_free_cursor($this->stmt);

                return $rs;
            } else {
                return parent::fetchAll($fetch_style, $column_index, $ctor_args);
            }
        } catch (Exception $e) {
            throw $e;
        }
    }

//

    public function fetchAllLob($fetch_style=null, $column_index =null, $ctor_args = null) {

        try {

            if (is_resource($this->stmt)) {

                $rs = array();
                while ($row = oci_fetch_array($this->stmt, OCI_ASSOC + OCI_RETURN_LOBS)) {
                    array_push($rs, $row);
                }

                oci_free_cursor($this->stmt);

                return $rs;
            } else {
                return parent::fetchAll($fetch_style, $column_index, $ctor_args);
            }
        } catch (Exception $e) {
            throw $e;
        }
    }

//

    public function fetchColumn($column_number=1) {

        try {

            if (is_resource($this->stmt)) {

                oci_fetch($this->stmt);
                return oci_result($this->stmt, 1);
            } else {
                return parent::fetchColumn($column_number);
            }
        } catch (Exception $e) {
            throw $e;
        }
    }

//

    /**
     *
     * @param $class_name
     * @param $ctor_args
     *
     */
    public function fetchObject($class_name=null, $ctor_args = null) {
        try {
            if (is_resource($this->stmt)) {
                $obj = oci_fetch_object($this->stmt);
                if (is_object($obj)) {
                    $r = new ReflectionObject($obj);
                    $attrs = $r->getProperties();
                    foreach ($attrs as $rpp) {
                        $obj->{strtolower($rpp->name)} = $obj->{$rpp->name};
                    }
                    if ($class_name == null || $class_name == 'stdClass') {
                        return $obj;
                    } else {
                        $r = new ReflectionClass($class_name);
                        $class = $r->newInstance(Rebel_DB_ORM_Util::dtoToArray($obj));
                        return $class;
                    }
                } else {
                    return null;
                }
            } else {
                return parent::fetchObject($class_name, $ctor_args);
            }
        } catch (Exception $e) {
            throw $e;
        }
    }

//

    public static function savelob($lob_upload) {
        
    }

//	mixed getAttribute ( int $attribute )
//	array getColumnMeta ( int $column )
//	bool nextRowset ( void )
//	int rowCount ( void )
//	bool setAttribute ( int $attribute , mixed $value )
//	bool setFetchMode ( int $mode )*/
}

///
